package services;

import domain.entities.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: nico
 * Date: 22/08/12
 * Time: 13:04
 * To change this template use File | Settings | File Templates.
 */
@Service
public class InvestigatorCRUDService implements CRUDService<Involucrado>{

    private InvolucradoDAO involucradoDAO;
    private CentroDAO centroDAO;
    private SpecialtyDAO specialtyDAO;
    private TherapeuticAreaDAO therapeuticAreaDAO;
    private RoleDAO roleDAO;

    public InvestigatorCRUDService() {
    }

    @Autowired
    public InvestigatorCRUDService(InvolucradoDAO involucradoDAO, CentroDAO centroDAO, SpecialtyDAO specialtyDAO, TherapeuticAreaDAO therapeuticAreaDAO, RoleDAO roleDAO) {
        this.involucradoDAO = involucradoDAO;
        this.centroDAO = centroDAO;
        this.specialtyDAO = specialtyDAO;
        this.therapeuticAreaDAO = therapeuticAreaDAO;
        this.roleDAO = roleDAO;
    }

    @Override
    public <V extends Criteria> List<Involucrado> list(V criteria) {
        List<Involucrado> list = involucradoDAO.findAll();
        Iterator<Involucrado> it = list.iterator();
        while(it.hasNext()){
            if(!criteria.isIn(it.next())){
                it.remove();
            }
        }
        return list;
    }

    public void save(Involucrado involucrado){

        if(involucrado.getSpeciality() != null){
            involucrado.setSpeciality(specialtyDAO.findById(involucrado.getSpeciality().getId()));
        }

        if(involucrado.getTherapeuticArea() != null){
            involucrado.setTherapeuticArea(therapeuticAreaDAO.findById(involucrado.getTherapeuticArea().getId()));
        }

        if(involucrado.getCentro() != null){
            involucrado.setCentro(centroDAO.findById(involucrado.getCentro().getId()));
        }
        involucradoDAO.attachDirty(involucrado);
    }

    public void delete(Involucrado involucrado) {
        involucradoDAO.delete((domain.entities.Involucrado) involucrado);
    }

    public Involucrado getById(int editableInvestigatorId) {
        return involucradoDAO.findById(editableInvestigatorId);
    }

    public List<Involucrado> findByCuit(String cuit) {
        return involucradoDAO.findByCuit(cuit);
    }

    public List<Involucrado> findByCnpj(String cnpj) {
        return involucradoDAO.findByCnpj(cnpj);
    }

    public List<Involucrado> findByNit(String nit) {
        return involucradoDAO.findByNit(nit);
    }

    public List<Involucrado> findByRut(String rut) {
        return involucradoDAO.findByCnpj(rut);
    }

    public List<Involucrado> findInvestigators(){
        return involucradoDAO.findByProperty("role", roleDAO.findByDescripcion("Investigator").get(0));
    }

    public List<Involucrado> findByNameOrSurname(String nameOrSurname) {
        Criteria cr = new CriteriaByNameOrSurname(nameOrSurname);
        return list(cr);
    }

    public List<Involucrado> findByNameOrSurnameSite(String nameOrSurname, Integer siteid) {
        Criteria cr = new CriteriaByNameOrSurname(nameOrSurname);


        return list(cr);
    }

    private class CriteriaByNameOrSurname extends Criteria{

        private String nameOrSurname;

        public CriteriaByNameOrSurname(String nameOrSurname) {
            this.nameOrSurname = nameOrSurname;
        }

        @Override
        public boolean isIn(Object element){
            boolean isIn = true;

            Involucrado other = (domain.entities.Involucrado)element;

            isIn &= isSubstring(nameOrSurname,other.getNombre()) || isSubstring(nameOrSurname,other.getApellido());

            //TODO: check for investigator type

            return isIn;
        }
    }
}